home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1993-03-06 | 38.0 KB | 1,201 lines
yakIcons 2.0 documentation: support modules! The operation of a computer game is a fairly complex thing. User input, program output, and disk access must all be juggled by the program. yakIcons can help! --------------------------------------------------------------------------- THE YAKLIB CLASS As you can imagine, an average-to-poor animation sequence length of only five frames can quickly get out of hand as one eight-direction factor has 9 positions * five frames/animation = wow, 45 files on disk for one actor! That's excessive, and that's why you need a yakLib to keep things straight. If you've ever used disk archiving programs like zip and arj, you've got the idea behind a yakLib. No compression is done, however, so graphics can make yakLibs big fast. yakLibs have a ".yar" extension, for "Yak ARchive" and can be easily manip- ulated with the "yar.exe" program. #ifndef YAKLIB.H #define YAKLIB.H #include "stddefs.h" #include <fstream.h> class directoryEntry { public: char filename[15]; unsigned long index; unsigned long size; directoryEntry() {filename[0] = '\0'; index = 0; size = 0;}; }; class yakLib { fstream myDataFile; int numberOfEntries; long directoryIndex; char libFilename[15]; public: void open(char * filename); yakLib(char * filename); void getDirectoryIndex(void); directoryEntry getIndex(char * filename); void addFile(char *filename); unsigned long fileSize(char * filename); void extractFile(char *filename); int deleteFile(char *filename); void listFiles(void); byte * loadToMem(char *filename); }; byte * loadDosToMem(char *filename); #endif class yakLib { fstream myDataFile; //the actual data file stream. int numberOfEntries; //number of entries in the yakLib long directoryIndex; //position in yakLib file of the directory entries char libFilename[15]; //filename of the yakLib public: void open(char * filename); opens the yakLib, sets directoryIndex! yakLib(char * filename); constructor, opens yakLib with the given filename void getDirectoryIndex(void); finds directory index of the yakLib directoryEntry getIndex(char * filename); gets index of a given file (index = position in yakLib file) void addFile(char *filename); adds a file to the yakLib unsigned long fileSize(char * filename); returns size of the specified file (in bytes) void extractFile(char *filename); extracts a file to disk int deleteFile(char *filename); removes a file from the yakLib void listFiles(void); lists files in yakLib byte * loadToMem(char *filename); allocates memory, loads a file from the lib into memory, and returns a pointer to the allocated block! }; ------------------------------------------------------------------------ THE YAKPALETTE CLASS the yakPalette class provides for fast, effective, and easy palette man- ipulation. See testi.exe for examples. Palettes come in .ypl format or .pal format (loaded with loadDM256). #ifndef YAKPAL.H #define YAKPAL.H #include "stddefs.h" #include "yaklib.h" class yakPalette { public: byte far paletteData[768]; enum direction {down, up}; yakPalette(void) {}; void load(char *filename, yakLib * myYakLib = NULL); void loadDM256(char * filename); void save(char *filename); void get(word startColor = 0, word numColors = 256); void put(word startColor = 0, word numColors = 256); yakPalette(char * filename, yakLib * myYakLib = NULL) {load(filename, myYakLib);}; void rotate(direction myDirection, word startColor = 0, word numColors = 256); void setColor(byte color, byte r, byte g, byte b); void fade(char intensity, word startColor = 0, word numColors = 256); }; #endif public: byte far paletteData[768]; //the actual palette data enum direction {down, up}; //enumerated type for palette rotation yakPalette(void) {}; //default constructor void load(char *filename, yakLib * myYakLib = NULL); loads a .ypl palette into the data area, optionally from yakLib. void loadDM256(char * filename); loads a .pal palette into the data area. void save(char *filename); saves a .ypl format palette void get(word startColor = 0, word numColors = 256); reads palette from DAC to data area void put(word startColor = 0, word numColors = 256); puts palette from data area to DAC yakPalette(char * filename, yakLib * myYakLib = NULL) {load(filename, myYakLib);}; constructor which loads palette void rotate(direction myDirection, word startColor = 0, word numColors = 256); rotates the given range of colors one color in myDirection. Put back to screen to see effect. void setColor(byte color, byte r, byte g, byte b); Sets a color in the palette to (r,g,b) values. void fade(char intensity, word startColor = 0, word numColors = 256); Reduces or increases intensity of range of colors by a value of intensity. positive--brighter, negative--darker. }; --------------------------------------------------------------------------- THE YAKFONT CLASS Fonts are of primary importance in any game, as more than likely text will be required at some point! #include "stddefs.h" #include "yakLib.h" #include "yakwin.h" #include "xlib.h" #include "xtext.h" class yakFont { public: word startChar; //ascii code of first character in font byte charHeight; //height of characters byte charWidth; //width of characters byte *fontData; //data for characters in font, includes first three items //(ie character data starts at fontData[4]) byte numberOfChars; yakFont(int iStartChar, int iCharWidth, int iCharHeight, int numChars) {startChar = iStartChar; charWidth = iCharWidth; charHeight = iCharHeight; fontData = new byte[(int)numChars * (int)charHeight + 4];}; yakFont(void) {startChar = 0; charHeight = charWidth = 0; fontData = NULL; numberOfChars = 0;}; void load(char * filename, yakLib * myYakLib = NULL); yakFont(char * filename, yakLib * myYakLib = NULL) {fontData = NULL; load(filename, myYakLib);}; void registerMe(void); void save(char * filename); void use(void); }; public: word startChar; //ascii code of first character in font byte charHeight; //height of characters byte charWidth; //width of characters byte *fontData; //data for characters in font, includes first three items //(ie character data starts at fontData[4]) byte numberOfChars; //three guesses! yakFont(int iStartChar, int iCharWidth, int iCharHeight, int numChars) {startChar = iStartChar; charWidth = iCharWidth; charHeight = iCharHeight; fontData = new byte[(int)numChars * (int)charHeight + 4];}; constructor. yakFont(void) {startChar = 0; charHeight = charWidth = 0; fontData = NULL; numberOfChars = 0;}; default constructor void load(char * filename, yakLib * myYakLib = NULL); loads font from disk (with yakLib if given) yakFont(char * filename, yakLib * myYakLib = NULL) {fontData = NULL; load(filename, myYakLib);}; loading constructor. void registerMe(void); registers font with xlib. void save(char * filename); saves font to disk void use(void); registers then enables the font. look at yfedit.cpp for examples! ------------------------------------------------------------------------ THE YAKWINDOWS CLASSES In windows fashion, the yakWindowPane is a rectangular area of screen which can save or restore itself. Useful for cleaning up sprites, dialog boxes, or anything! //contains header information for the yakWindows classes; at this //stage, just yakWindowPane #ifndef YAKWIN.H #define YAKWIN.H #include "stddefs.h" #include "xlib.h" #include <stdlib.h> class yakWindowPane { public: word x, y, width, bWidth, height, myOffset; //bwidth is width in nibbles far byte * myGraphicData; yakWindowPane(void) {x = y = bWidth = height = myOffset = 0; myGraphicData = NULL;}; yakWindowPane(word x1, word y1, word x2, word y2); ~yakWindowPane() {delete myGraphicData;}; void reSave(word x1, word y1, word x2, word y2, word offset); void save(word x1, word y1, word offset); void save(void); void restore(word offset); void restore(void); }; class yakWindow : public yakWindowPane { public: static yakWindow * killPointer; enum flags {isSizeable = 0x01, isDraggable = 0x02, isCloseable = 0x04, isTemporary = 0x08}; word myNumber; flags myFlags; byte titleBarColor, textColor, boxColor; char title[80]; yakWindow * nextWindow, * prevWindow; static yakWindow * bottomWindow, * topWindow; static yakWindow * activeWindow; yakWindow(int x1, int y1, int x2, int y2); void open(void); void close(void); void showActivated(void); void showActivated(word offset); void showDeActivated(void); void showDeActivated(word offset); virtual void draw(word offset); //redefine this one! virtual void draw(void); void shuffleToTop(void); virtual word interpretMouseClick(void); virtual word interpretKeyStroke(char myChar); void drag(void); void size(void); virtual int isSelected(void); virtual int isDragSelected(void); virtual int isSizeSelected(void); virtual int isCloseSelected(void); static void drawAll(void); static void selectToTop(void); static word advance(void); }; #endif class yakWindowPane { public: word x, y, width, bWidth, height, myOffset; //bwidth is width in nibbles (groups //of 4 pixels far byte * myGraphicData; //where video memory is copied to yakWindowPane(void) {x = y = bWidth = height = myOffset = 0; myGraphicData = NULL;}; default const. yakWindowPane(word x1, word y1, word x2, word y2); constructor which takes coords of the top left and bottom right corners ~yakWindowPane() {delete myGraphicData;}; default destructor; frees up memory used by the windowpane. void reSave(word x1, word y1, word x2, word y2, word offset); saves screen memory into myGraphicData, reallocating if necessary void save(word x1, word y1, word offset); saves screen memory into myGraphicData using current bwidth and height void save(void); saves screen memory into myGraphicData using current position, bwidth, height, and offset. void restore(word offset); restores screen memory from myGraphicData using current position, bwidth, and height void restore(void); like above but uses current offset. }; class yakWindow : public yakWindowPane { public: static yakWindow * killPointer; holds the address of the next window to be closed when the manager is called. enum flags {isSizeable = 0x01, isDraggable = 0x02, isCloseable = 0x04, isTemporary = 0x08}; These flags contain the different options for a window. Is it sizeable, draggable, closeable, or temporary (deleted when closed)? word myNumber; Window number. flags myFlags; this window's flags. byte titleBarColor, textColor, boxColor; used for drawing. char title[80]; text displayed at top of this window. yakWindow * nextWindow, * prevWindow; pointers to the surrounding windows in the stack. static yakWindow * bottomWindow, * topWindow; Addresses of the top and bottom windows. static yakWindow * activeWindow; Window to recieve mouse signals and keyboard inputs. yakWindow(int x1, int y1, int x2, int y2); Default constructor. void open(void); opens the window on screen. void close(void); restores the background and closes the window. void showActivated(void); void showActivated(word offset); Displays the window as "activated" void showDeActivated(void); void showDeActivated(word offset); displays the window as "deactivated". virtual void draw(word offset); //redefine this one! virtual void draw(void); The actual code to draw the window. Redefine in derived classes for endless versatility. void shuffleToTop(void); Moves the window to the top of the stack. virtual word interpretMouseClick(void); Tells the window how to interpret a mouse click. virtual word interpretKeyStroke(char myChar); Tells the window how to interpret a key stroke. void drag(void); Drags the window to a new position. void size(void); Stretches the window to a new size. virtual int isSelected(void); Checks to see if the window is selected. virtual int isDragSelected(void); ...dragged, virtual int isSizeSelected(void); ...resizing, virtual int isCloseSelected(void); ...or closing. static void drawAll(void); Draws all windows from bottom to top of the window stack. For restoring the screen. static void selectToTop(void); Selects the mouse-selected window to the top of the stack. static word advance(void); Advances the window stack. If any mouse events are waiting, advance() sends them to the appropriate window. Same with keyboard. }; ------------------------------------------------------------------------ THE YAKSCROLLER CLASS Of paramount importance to information oriented games is the dialog box, where the program can spit out text which the user scrolls through as he wishes. The yakScroller does this, then cleans up the screen after itself like a window! See testi.cpp for an example. YakScrollers are wordwrapped, so don't worry about that. #include "stddefs.h" #include "yakLib.h" #include "yakwin.h" #include "xlib.h" #include "xtext.h" class yakScroller : public yakWindow { public: int position; //position is the line # at top. enum direction {up, down}; char * myText; yakScroller(word x1, word y1, word x2, word y2, char * imyText, int iposition = 0) : yakWindow(x1, y1, x2, y2) {myText = imyText; position = iposition;}; ~yakScroller() {delete myText;}; virtual void draw(word offset = VisiblePageOffs); virtual word interpretKeyStroke(char myChar); virtual word interpretMouseClick(void); char * getLine(word lineNumber); int lineLength(word lineNumber); void drawLine(int lineNumber, int x, int y, word offset); void activate(int x, int y, word offset = VisiblePageOffs); void drawText(int lineNumber, int ix, int iy, word offset = VisiblePageOffs); void drawText(int lineNumber, word offset = VisiblePageOffs); void drawText(word offset = VisiblePageOffs); void newText(byte * theNewText); void activate(int x1, int y1, int x2, int y2, word offset, char * theNewText); void pageMove(direction pageDirection, word offset = VisiblePageOffs); void lineMove(direction lineDirection, word offset = VisiblePageOffs); }; { public: int position; //position is the line # at top. enum direction {up, down}; //direction type for scrolling char * myText; //text shown in the box yakScroller(word x1, word y1, word x2, word y2, char * imyText, byte iBorderColor = 10, byte iBoxColor = 0, byte itextColor = 15, int iposition = 0) : yakWindowPane(x1, y1, x2, y2) {width = x2-x1; myText = imyText; borderColor = iBorderColor; boxColor = iBoxColor; textColor = itextColor; position = iposition;}; constructor for yakScroller using diagonal corners, etc. ~yakScroller() {delete myText;}; default destructor. void draw(word offset = VisiblePageOffs); draws yakScroller using current coords virtual word interpretKeyStroke(char myChar); virtual word interpretMouseClick(void); Tells the yakScroller how to interpret clicks and keystrokes. The top and bottom bars of the yakscroller scroll the text in the appropriate direction if clicked on. Arrow keys and pgUp/Dn also work. char * getLine(word lineNumber); gets position in memory of the line <linenumber>, correcting for wordwrap int lineLength(word lineNumber); returns length of a given line number. void drawLine(int lineNumber, int x, int y, word offset); draws a line of text void activate(int x, int y, word offset = VisiblePageOffs); activates scroller at given position and offset, allowing the user to scroll text with the up/down arrows and pageup/pagedown. void drawText(int lineNumber, int ix, int iy, word offset = VisiblePageOffs); fills box with text starting with lineNumber at given coords. void drawText(int lineNumber, word offset = VisiblePageOffs); fills box with text starting at lineNumber at current coords. void drawText(word offset = VisiblePageOffs); fills box with text starting at <position> at current coords. void newText(byte * theNewText); frees memory at myText and reassigns it. This could be hazardous if you're not careful. void activate(int x1, int y1, int x2, int y2, word offset, char * theNewText); activates using diagonal box coordinates, given offset, and new text. void pageMove(direction pageDirection, word offset = VisiblePageOffs); scrolls display one page in pageDirection. void lineMove(direction lineDirection, word offset = VisiblePageOffs); scrolls display one line in lineDirection. }; ------------------------------------------------------------------------- THE YAKSAMPLE CLASS I haven't toyed too much with this, but I've heard it work! Sampled sounds are important for games, and the Soundblaster is a good way to implement them. To make this easier, try the yakSample class! See the soundtst.cpp program for example! #ifndef YAKSOUND.H #define YAKSOUND.H #include <dos.h> #include "yaklib.h" class yakSample { public: byte * sampleData; unsigned long sampleLength; void play(word sampleRate = 11000, word stereo = 1, word voice = 1, unsigned long length = 0); yakSample(void) {sampleData = NULL;}; yakSample(char * filename) {sampleData = NULL; load(filename);}; byte * load(char * filename); }; class yakVoc { public: byte * sampleData; void load(char * filename, yakLib * myYakLib = NULL); void play(void); }; void CTLoad(void); int CTGetVersion(void); void CTSetIOAddr(int base); void CTSetIRQ(int irq); int CTInitialize(void); void CTUninstall(void); void CTSpeakerOn(void); void CTSpeakerOff(void); void CTSetStatusWord(word * address); void CTOutputVoice(char * buffer); void CTInputVoice(int sampleRate, char* buffer, long length); void CTStopVoiceProcess(void); int CTPauseOutputVoice(void); int CTContinueOutputVoice(void); #endif { public: byte * sampleData; //data in memory of sound sample unsigned long sampleLength; //three guesses void play(word sampleRate = 11000, word stereo = 1, word voice = 1, unsigned long length = 0); plays this sample using DMA channels yakSample(void) {sampleData = NULL;}; def. const. yakSample(char * filename) {sampleData = NULL; load(filename);}; const which loads sample. byte * load(char * filename); loads sample from disk. Does not implement yakLib, but this is easy to do (ie myYakSample.sampleData = myYakLib.loadToMem("spam.sam");) }; class yakVoc { public: byte * sampleData; Sound data void load(char * filename, yakLib * myYakLib = NULL); Loads a .voc file from disk void play(void); plays the voc file. }; void CTLoad(void); int CTGetVersion(void); void CTSetIOAddr(int base); void CTSetIRQ(int irq); int CTInitialize(void); void CTUninstall(void); void CTSpeakerOn(void); void CTSpeakerOff(void); void CTSetStatusWord(word * address); void CTOutputVoice(char * buffer); void CTInputVoice(int sampleRate, char* buffer, long length); void CTStopVoiceProcess(void); int CTPauseOutputVoice(void); int CTContinueOutputVoice(void); These are all from the Soundblaster Freedom Project. They manipulate the CT-VOICE.DRV driver for the soundblaster. Documentation is sketchy as of now. Look at driver.cpp for some examples of use. -------------------------------------------------------------------------- THE YAKSTICK CLASS The joystick is possibly the most popular game input device. No gamer should be without a joystick object! See testi.cpp for an example #include "stddefs.h" #ifndef YAKSTICK.H #define YAKSTICK.H extern int jsense; //sensitivity of stick? extern int jrange; //range of output values? Play with these! class yakStick //joystick class object! { public: byte stickNumber; int x, y; byte button1, button2; yakStick(byte number) {stickNumber = number; x=y=0; button1=button2=0; jsense = 10; jrange = 200;}; int read(void); int readX(void); int readY(void); byte readButton1(void); byte readButton2(void); }; #endif { public: byte stickNumber; //id number of joystick int x, y; //x and y of stick position byte button1, button2; //0 if off, >0 if on yakStick(byte number) {stickNumber = number; x=y=0; button1=button2=0; jsense = 10; jrange = 200;}; creates a yakStick object with ID <number> int read(void); reads values into x, y, and buttons. int readX(void); reads joystick and returns x int readY(void); reads joystick and returns y byte readButton1(void); reads joystick and returns button1 byte readButton2(void); reads joystick and returns button2 }; yakstick.cpp uses jstcka.asm (or something like that). Be sure it's compiled. yakstick.cpp also defines "extern yakStick joyStick1, joyStick2" for use in your programs, ie you shouldn't ever have to declare an instance of yakStick. --------------------------------------------------------------------------- THE YAKMOUSE CLASS If the joystick is the preferred input device of action games, the mouse is the clear winner with everything else. EVERYTHING seems to use mice these days, whether we like it or not, and mouse programming is a messy, interrupt- oriented process... until now. See yedit.cpp for examples! #ifndef YAKMOUSE.H #define YAKMOUSE.H #include "icon.h" class yakMouse { public: enum buttonType {noButtons = 0, leftButton = 0x01, rightButton = 0x02, reset = 0xff, eitherButton = 0x03}; void init(void); void remove(void); void show(void); void hide(void); void beStandardMouse(void); void setImage(char * mouseDef, int color); word x(void); word y(void); // word numberOfButtons(void); void display(int x, int y, int topclip, int botclip, word offset); word buttonStatus(void); byte isPressed(buttonType myButtons); byte isClicked(buttonType myButtons); byte isInBox(int x1, int y1, int x2, int y2); }; #endif class yakMouse { public: enum buttonType {noButtons = 0, leftButton = 0x01, rightButton = 0x02, reset = 0xff, eitherButton = 0x03}; //mask for isPressed, isClicked void init(void); initializes mouse driver. Do this before anything else. void remove(void); deinitializes mouse driver. A good idea before leaving the program! void show(void); Shows mouse at current position. void hide(void); Hides mouse. void beStandardMouse(void); Sets mouse to my standard mouse. The mouse has a "notch" in it for a reason: to check the color of the pixel "under" the mouse, it has to be transparent; otherwise x_get_pix says "yep, it's white all right." void setImage(char * mouseDef, int color); Sets image of mouse to mouseDef. See formats.doc for this format word x(void); reads mouse; returns x coord word y(void); reads mouse; returns y coord // word numberOfButtons(void); removed since xlib04 didn't support it. void display(int x, int y, int topclip, int botclip, word offset); draws mouse cursor at given position. A must for page-flipping, which confuses herr rodent. word buttonStatus(void); returns status of the button variable. byte isPressed(buttonType myButtons); returns 0 if mask does not apply, >0 if it does. Use like this: if (isPressed(yakMouse::leftButton)). Returns if the button is currently pressed. byte isClicked(buttonType myButtons); Checks button status. If the status has changed since last check and the button is down, returns nonzero value. Good for toggle switches (see gadgets!) byte isInBox(int x1, int y1, int x2, int y2); returns 1 if the mouse cursor is in the specified rectangle on screen. Useful for detecting clicks on objects. }; Note! The yakMouse.cpp already has an "extern yakMouse mouse" defined; you shouldn't have to define your own mouse! ----------------------------------------------------------------------------- THE YAKKEYBOARD CLASS The problem with keyboard input is that for the most part it's hard to decide what keys are being pressed, especially if two or more are being pressed in combination. The yakKeyboard class takes care of this for you. #ifndef YAKKEYS.H #include "stddefs.h" #define YAKKEYS.H //header file for yakKeyboard; adapted from STK code by Jari Karjala class yakKeyboard { public: enum keyLabel {escape = 1, num1, num2, num3, num4, num5, num6, num7, num8, num9, num0, tab=15, charQ, charW, charE, charR, charT, charY, charU, charI, charO, charP, charA=30, charS, charD, charF, charG, charH, charJ, charK, charL, charZ=44, charX, charC, charV, charB, charN, charM, keyComma, keyDot, spaceBar=57, upArrow = 72, downArrow=80, leftArrow = 75, rightArrow = 77}; static char keys[128]; static char * bufferHead, bufferTail; static void interrupt (*oldHandler)(...); static void interrupt newHandler(...); static void install(void); static void remove(void); }; #ifndef YAKKEYSUNIT extern yakKeyboard keyboard; #endif #endif class yakKeyboard { public: enum keyLabel {escape = 1, num1, num2, num3, num4, num5, num6, num7, num8, num9, num0, tab=15, charQ, charW, charE, charR, charT, charY, charU, charI, charO, charP, charA=30, charS, charD, charF, charG, charH, charJ, charK, charL, charZ=44, charX, charC, charV, charB, charN, charM, keyComma, keyDot, spaceBar=57, upArrow = 72, downArrow=80, leftArrow = 75, rightArrow = 77}; The different keys available. static char keys[128]; The keyboard "buffer"-- if keys[yakKeyboard::charQ] != 0, the "q" key is being pressed. static char * bufferHead, bufferTail; Head and tail of the keyboard buffer. static void interrupt (*oldHandler)(...); static void interrupt newHandler(...); The old and new handlers for the keyboard. static void install(void); Installs new handler... static void remove(void); ...and removes it. }; ----------------------------------------------------------------------------- THE GADGET CLASS HIERARCHY I worked long and hard on this. Lots of packages claim they have mouse support while just doing what the simple yakMouse class does. I do them better! The gadget hierarchy is an object-oriented hierarchy of four types of gadgets: buttons (return a given value when you click on them), switches (return their current position, which changes when you click on them), sliders (which are like continuously variable switches), and labels (which are just bits of text that work like buttons). Used with a gadgetList, you can have a bank of buttons or switches that are automatically updated with little or no effort from the programmer. See the demo program for code examples. #ifndef GADGETS.H #define GADGETS.H #include "animicon.h" #include "yakmouse.h" #include "xlib.h" #define HELP_MASK 4096 class gadget : public animicon { public: enum flagType {normal = 0, touchPad = 1}; enum gadgetType {buttonType = 1, pSwitchType = 2, sliderType = 3}; virtual byte isSelected(void); word x, y; word relX, relY; //used by gadgetManager char commandChar; flagType flags; gadgetType type; gadget(char commandChar, char * filename, icon::flagType aflags = icon::normal, yakLib * myYakLib = NULL, gadget::flagType iflags = gadget::normal, int ix = 0, int iy = 0); gadget(char icommandChar, animiconNode * thisFrame, gadget::flagType iflags = gadget::normal, int ix = 0, int iy=0); gadget(void) : animicon() {x = y = 0; commandChar = 0; flags = normal;}; virtual void draw(int ix, int iy, word offset) {x=ix; y=iy; animicon::draw(x, y, offset);}; virtual void draw(word offset = VisiblePageOffs) {draw(x, y, offset);}; virtual int activate(void) = 0; virtual int status(void) = 0; }; class button : public gadget { public: int returnValue; button(int ix, int iy, char commandChar, int returnValue, char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL, gadget::flagType iflags = gadget::normal); virtual int activate(void); virtual int status(void); }; class label : public button { public: char * myText; byte fgColor, bgColor; label(int ix, int iy, char commandChar, int returnValue, char * text, byte ifgColor = 15, byte ibgColor = 0, gadget::flagType iflags = gadget::normal); virtual void draw(int ix, int iy, word offset); virtual byte isSelected(void); }; class pSwitch : public gadget { public: int position; pSwitch(int ix, int iy, char commandChar, char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL, gadget::flagType iflags = gadget::normal); virtual int activate(void); virtual int status(void); }; class slider : public gadget { public: int position, width, height; int minimumValue, maximumValue; byte barColor, borderColor, indicatorColor; slider(int ix, int iy, int iwidth, int iheight, int minimumValue, int maximumValue, byte barColor = 0, byte borderColor = 10, byte indicatorColor = 25); slider() : gadget() {position = width = height = minimumValue = maximumValue = 0; position = width = height = 0;}; virtual void draw(word offset = VisiblePageOffs); virtual void draw(int x, int y, word offset); virtual int activate(void); virtual int status(void); }; //Node definitions Follow------------------------------------------> class gadgetNode { public: gadgetNode * nextGadget; gadgetNode * prevGadget; gadget * thisGadget; gadgetNode(gadget * newGadget, gadgetNode * newNextGadget) {nextGadget = newNextGadget; thisGadget = newGadget, prevGadget = NULL;}; }; //list definitions follow-----------------------------------------> class gadgetList { public: gadgetNode * firstGadget; gadgetNode * lastGadget; virtual int status(void); gadgetList() {firstGadget = lastGadget = NULL;}; void draw(int x, int y, word offset = VisiblePageOffs); void draw(word offset = VisiblePageOffs); void add(gadgetNode * theNewGadget); }; #endif THE GADGET CLASS #define HELP_MASK 4096 -- optionally, you can use the help mask to return (4096 LOGICAL-OR returnValue) for buttons to use as a "help" feature. Not implemented fully. class gadget : public animicon { public: enum flagType {normal = 0, touchPad = 1}; a normal icon is activated by clicking on it. A touchPad is activated when- ever the mouse is on it and the cursor is down. There's a difference! Look at the grumjug switch in ymsedemo.cpp; it's a touchpad, while the toggle is a normal. enum gadgetType {buttonType = 1, pSwitchType = 2, sliderType = 3}; used to see what kind of a gadget we have. Buttons return values when activated; all others must be individually checked. virtual byte isSelected(void); Is the icon selected? Checks to see if the mouse is on the icon, if the pixel under the cursor really belongs to the icon (stacked icons, like piles of objects on a map?), checks to see if the gadget's commandChar was pressed, and returns 1 if the gadget was selected. word x, y; position of the gadget word relX, relY; used by gadgetManager; relative position of the gadget in the gadgetManager. char commandChar; when pressed, this character activates the gadget. flagType flags; normal or touchpad? gadgetType type; What kind of gadget? gadget(char commandChar, char * filename, icon::flagType aflags = icon::normal, yakLib * myYakLib = NULL, gadget::flagType iflags = gadget::normal, int ix = 0, int iy = 0); Mondo constructor. Initializes commandChar, loads the animicon from filename, sets flags, sets position. gadget(char icommandChar, animiconNode * thisFrame, gadget::flagType iflags = gadget::normal, int ix = 0, int iy=0); Another constructor; adds from a pre-made animiconNode instead of a file. gadget(void) : animicon() {x = y = 0; commandChar = 0; flags = normal;}; def. const. virtual void draw(int ix, int iy, word offset) {x=ix; y=iy; animicon::draw(x, y, offset);}; draws gadget at given position. virtual void draw(word offset = VisiblePageOffs) {draw(x, y, offset);}; draws gadget at current position. virtual int activate(void) = 0; activates the icon (flips the switch, slides the slider, whatever) virtual int status(void) = 0; activates the icon if applicable and returns its status. }; THE BUTTON CLASS Buttons, when pressed, return their return value. By knowing what these are, programs can act on a button's press. Uses one frame of animation. class button : public gadget { public: int returnValue; what value this will return when activated. button(int ix, int iy, char commandChar, int returnValue, char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL, gadget::flagType iflags = gadget::normal); mondo constructor. virtual int activate(void); virtual int status(void); }; THE LABEL CLASS The label class acts just like a button. However, they display a segment of text instead of an icon. class label : public button { public: char * myText; text to display byte fgColor, bgColor; Foreground and background color of the text. label(int ix, int iy, char commandChar, int returnValue, char * text, byte ifgColor = 15, byte ibgColor = 0, gadget::flagType iflags = gadget::normal); Constructor. virtual void draw(int ix, int iy, word offset); Self-explanatory. virtual byte isSelected(void); Self-explanatory. }; THE SWITCH CLASS Switches, when pressed, advance to their next position. They have as many positions possible as they have frames of animation, ie an animation with two frames (togg.yak and togg2.yak) has two positions. class pSwitch : public gadget { public: int position; current position of switch pSwitch(int ix, int iy, char commandChar, char * filename, icon::flagType flags = icon::normal, yakLib * myYakLib = NULL, gadget::flagType iflags = gadget::normal); mondo constructor virtual int activate(void); virtual int status(void); status() returns the position of the switch. }; THE SLIDER CLASS You've seen sliders before. They have a low value, a high value, and a current position and look like a bar graph. If you never check to see if they're selected, they make swell bar graphs for fuel, hit points, or whatever as well! A very useful object! class slider : public gadget { public: int position, width, height; //position:position of slider. width and //height are the dimensions of the object int minimumValue, maximumValue; //min and max of the slider byte barColor, borderColor, indicatorColor; //three guesses. slider(int ix, int iy, int iwidth, int iheight, int minimumValue, int maximumValue, byte barColor = 0, byte borderColor = 10, byte indicatorColor = 25); Mondo constructor. slider() : gadget() {position = width = height = minimumValue = maximumValue = 0; position = width = height = 0;}; default constructor. virtual void draw(word offset = VisiblePageOffs); draws at current coords. virtual void draw(int x, int y, word offset); draws at given coords virtual int activate(void); activates slider and sets position. virtual int status(void); returns position of slider }; THE GADGETNODE CLASS The gadgetNode is an element of a gadgetList, a simple linked-list structure. class gadgetNode { public: gadgetNode * nextGadget; next gadget in the list. gadgetNode * prevGadget; Previous gadget in the list. gadget * thisGadget; The current gadget. gadgetNode(gadget * newGadget, gadgetNode * newNextGadget) {nextGadget = newNextGadget; thisGadget = newGadget, prevGadget = NULL;}; Constructor. Note the newNextGadget argument-- replace it with another gadgetNode constructor, and several gadgets can be added at once. See the demo program source code for examples. }; THE GADGETLIST CLASS A gadgetList consists of several nodes of gadgets, and updates them auto- matically. class gadgetList { public: gadgetNode * firstGadget; First gadget in the list. gadgetNode * lastGadget; Last gadget in the list. virtual int status(void); Status of the gadgetList. Returns the value of whatever button is being pressed and also updates all gadgets. gadgetList() {firstGadget = lastGadget = NULL;}; Constructor. void draw(int x, int y, word offset = VisiblePageOffs); void draw(word offset = VisiblePageOffs); Draws all gadgets in the list. void add(gadgetNode * theNewGadget); Adds a gadgetNode to the list. }; -------------------------------------------------------------------------- THE YAKPANEL CLASS Bringing together the best worlds-- layered windows and automatic gadgets-- is the yakPanel class. It's basically a yakWindow and a gadgetList in one; a window full of switches, buttons, or whatever that can be a menu, a control panel, or whatever. #include "stddefs.h" #include "yakwin.h" #include "gadgets.h" class yakPanel : public yakWindow, public gadgetList //control panel window { public: yakPanel(int x1, int y1, int x2, int y2) : yakWindow(x1,y1,x2,y2) {myFlags &= ~yakWindow::isSizeable;}; virtual word interpretKeyStroke(char myChar); virtual word interpretMouseClick(void); virtual void draw(word offset) {yakWindow::draw(offset); gadgetList::draw(x, y,offset);}; virtual int status(void); }; class yakPanel : public yakWindow, public gadgetList //control panel window { public: yakPanel(int x1, int y1, int x2, int y2) : yakWindow(x1,y1,x2,y2) {myFlags &= ~yakWindow::isSizeable;}; Default constructor. Since yakPanels draw themselves by drawing all their gadgets, we generally don't want them to be sizeable. virtual word interpretKeyStroke(char myChar); virtual word interpretMouseClick(void); YakPanel versions of these functions. virtual void draw(word offset) {yakWindow::draw(offset); gadgetList::draw(x, y,offset);}; virtual int status(void); ...and these. Treat it just like a yakWindow OR a yakPanel. It's that simple. See the demo program for easy ways to implement these. };